﻿using System;
using System.Windows.Media;

namespace Mongoose.Windows
{
    /// <summary>
    /// Extension methods for Visual
    /// </summary>
    public static class Visual_ExtensionMethods
    {
        /// <summary>
        /// Retrieves the first Descendant of the currren Visual in the VisualTree matching the given predicate
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="this">The current Visual.</param>
        /// <param name="predicate">An optional predicate that the descendant have to satisfy.</param>
        /// <returns></returns>
        public static T SafeFindDescendant<T>(this Visual @this, Predicate<T> predicate = null) where T : Visual
        {
            T result = null;
            if (@this == null)
            {
                return null;
            }

            // iterate on VisualTree children thanks to VisualTreeHelper
            int childrenCount = VisualTreeHelper.GetChildrenCount(@this);
            for (int i = 0; i < childrenCount; i++)
            {
                var currentChild = VisualTreeHelper.GetChild(@this, i);

                var typedChild = currentChild as T;
                if (typedChild == null)
                {
                    // recursive search
                    result = ((Visual)currentChild).SafeFindDescendant<T>(predicate);
                    if (result != null)
                    {
                        break;
                    }
                }
                else
                {
                    if (predicate == null || predicate(typedChild))
                    {
                        result = typedChild;
                        break;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Retrieves the first Ancestor of the currren Visual in the VisualTree matching the given predicate
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="this">The current Visual.</param>
        /// <param name="predicate">An optional predicate that the ancestor have to satisfy.</param>
        /// <returns></returns>
        public static T SafeFindAncestor<T>(this Visual @this, Predicate<T> predicate = null) where T : Visual
        {
            if (@this == null)
            {
                return null;
            }

            // retrieve Visual Parent thanks to VisualTreeHelper
            var parent = VisualTreeHelper.GetParent(@this);
            var typedParent = parent as T;

            return typedParent == null || (predicate != null && !predicate(typedParent)) ?
                ((Visual)parent).SafeFindAncestor<T>(predicate) : // recursive search
                typedParent; // ancestor found
        }
    }
}
